Skip to content

Conversation

@bburda
Copy link
Contributor

@bburda bburda commented Feb 7, 2026

Description

Full Docker-based demo of a Panda 7-DOF robot arm performing continuous pick-place-home cycles with ros2_medkit diagnostics and fault injection.

Simulation modes:

  • Gazebo Harmonic (default): physics simulation with gz_ros2_control
  • Fake hardware (--fake flag): mock controllers with RViz visualization

Components:

  • MoveIt 2 move_group with OMPL planner for motion planning
  • Joint-space targets for reliable pick/place/home cycling
  • ros2_medkit gateway, fault_manager, diagnostic_bridge
  • Manipulation monitor tracking joint limits, velocity, collision, planning failures, and controller timeouts
  • Manifest with 4 areas, 7 components, 10 apps, 4 functions

Scripts:

  • run-demo.sh / stop-demo.sh: Docker lifecycle management
  • move-arm.sh: interactive joint preset commands
  • inject-*.sh / restore-normal.sh: fault injection helpers
  • check-entities.sh / check-faults.sh: REST API inspection

Docker:

  • CPU and NVIDIA GPU profiles
  • Web UI (port 3000) and REST API (port 8080)
  • Headless and GUI modes supported

Related Issue

closes #12

Checklist

  • Tested locally
  • README updated (if needed)

@bburda bburda requested a review from mfaferek93 February 7, 2026 21:29
@bburda bburda self-assigned this Feb 7, 2026
@bburda bburda added the enhancement New feature or request label Feb 7, 2026
Copilot AI review requested due to automatic review settings February 7, 2026 21:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Docker-based MoveIt 2 Panda pick-and-place demo that integrates ros2_medkit (gateway + fault manager + diagnostic bridge), including continuous motion to support fault injection and SOVD entity modeling via a manifest.

Changes:

  • Introduces a complete demos/moveit_pick_place/ demo package (launch files, configs, Python nodes, Docker artifacts).
  • Adds helper scripts for running/stopping the demo, moving the arm, injecting faults, and inspecting entities/faults via REST.
  • Updates the repository root README to list and document the new demo.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 21 comments.

Show a summary per file
File Description
demos/moveit_pick_place/stop-demo.sh Stops demo containers and optionally removes volumes/images.
demos/moveit_pick_place/run-demo.sh Starts demo with CPU/NVIDIA profiles and fake/Gazebo modes.
demos/moveit_pick_place/docker-compose.yml Defines CPU + NVIDIA services and the web UI container.
demos/moveit_pick_place/Dockerfile Builds a Jazzy-based image with MoveIt + ros2_medkit and the demo package.
demos/moveit_pick_place/package.xml Declares the ROS package for the demo.
demos/moveit_pick_place/CMakeLists.txt Installs launch/config files and Python executables.
demos/moveit_pick_place/launch/demo.launch.py Fake-hardware launch including MoveIt demo launch + medkit stack + demo nodes.
demos/moveit_pick_place/launch/demo_gazebo.launch.py Gazebo Harmonic launch wiring robot description, controllers, MoveIt, medkit, and demo nodes.
demos/moveit_pick_place/scripts/pick_place_loop.py Continuous joint-goal pick/place/home loop via MoveGroup action.
demos/moveit_pick_place/scripts/manipulation_monitor.py Monitors action status + joint limits and reports faults to FaultManager.
demos/moveit_pick_place/config/moveit_controllers.yaml ros2_control controller configuration for arm/gripper.
demos/moveit_pick_place/config/medkit_params.yaml ros2_medkit gateway configuration (bind, CORS, discovery mode).
demos/moveit_pick_place/config/panda_manifest.yaml SOVD manifest defining areas/components/apps/functions for the demo.
demos/moveit_pick_place/config/panda_moveit.yaml Optional MoveIt parameter overrides.
demos/moveit_pick_place/move-arm.sh CLI helper to send FollowJointTrajectory goals to preset joint poses.
demos/moveit_pick_place/inject-planning-failure.sh Injects a planning failure via a blocking collision wall.
demos/moveit_pick_place/inject-grasp-failure.sh Injects an unreachable target by moving the object out of workspace.
demos/moveit_pick_place/inject-controller-timeout.sh Injects controller aborts via overly tight controller constraints.
demos/moveit_pick_place/inject-joint-limit.sh Injects joint limit approaching/violation via extreme joint commands.
demos/moveit_pick_place/inject-collision.sh Injects collision obstacles into the planning scene.
demos/moveit_pick_place/restore-normal.sh Removes injected objects/params and clears faults.
demos/moveit_pick_place/check-entities.sh Queries SOVD entities and sample data from the REST API.
demos/moveit_pick_place/check-faults.sh Queries and summarizes active faults from the REST API.
demos/moveit_pick_place/README.md Full demo documentation, usage, and fault injection guidance.
README.md Adds the new MoveIt pick-and-place demo to the repo overview and quick start.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 107 to 114
def execute_cycle(self):
"""One pick-and-place cycle step."""
if not self.move_group_ready:
return

Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execute_cycle() is driven by a periodic timer, but the node doesn’t track whether a previous MoveGroup goal is still executing. This can send overlapping goals, causing aborts and phase desync. Consider only dispatching the next goal after the prior result callback (or stop the timer while a goal is in flight).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — added goal_in_flight flag. execute_cycle() now skips if a previous goal is still executing. The flag is set before send_goal_async() and cleared in result_callback() (or on rejection).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — added a goal_in_flight flag. execute_cycle() now skips if a previous goal is still executing. The flag is set before send_goal_async() and cleared in result_callback() (or on rejection).

mfaferek93
mfaferek93 previously approved these changes Feb 8, 2026
Full Docker-based demo of a Panda 7-DOF robot arm performing continuous
pick-place-home cycles with ros2_medkit diagnostics and fault injection.

Simulation modes:
- Gazebo Harmonic (default): physics simulation with gz_ros2_control
- Fake hardware (--fake flag): mock controllers with RViz visualization

Components:
- MoveIt 2 move_group with OMPL planner for motion planning
- Joint-space targets for reliable pick/place/home cycling
- ros2_medkit gateway, fault_manager, diagnostic_bridge
- Manipulation monitor tracking joint limits, velocity, collision,
  planning failures, and controller timeouts
- Manifest with 4 areas, 7 components, 10 apps, 4 functions

Scripts:
- run-demo.sh / stop-demo.sh: Docker lifecycle management
- move-arm.sh: interactive joint preset commands
- inject-*.sh / restore-normal.sh: fault injection helpers
- check-entities.sh / check-faults.sh: REST API inspection

Docker:
- CPU and NVIDIA GPU profiles
- Web UI (port 3000) and REST API (port 8080)
- Headless and GUI modes supported
Scripts:
- Fix monitor topic /move_group/_action/status → /move_action/_action/status
- Fix injection scripts: use /apply_planning_scene service instead of
  unreliable ros2 topic pub --once
- Rewrite controller-timeout and joint-limit scripts to use gateway
  REST API instead of docker exec rclpy (DDS discovery issues)
- Fix restore script: use service call + REST API, add delay for
  PREFAILED timing
- Fix check-entities.sh: joint states jq path .name → .data.name
- Fix check-faults.sh: correct jq field names to match API response

Config:
- Add fault_manager config to medkit_params.yaml (snapshots, storage)
- Pass medkit_params_file to fault_manager in demo.launch.py

Docs:
- Fix monitored topics table and architecture diagram
- Fix verification jq example field names
- Add snapshot documentation and REST API configuration section
- Add injection limitation notes (fake hardware, single-goal controller)
- Add DDS/docker exec troubleshooting entries
- Update Docker image size estimate (~5-6 GB → ~7 GB)
Scripts:
- Add container auto-detection (CONTAINER_NAME env or grep for
  moveit_medkit_demo / moveit_medkit_demo_nvidia) in all docker exec
  scripts (inject-*, restore-normal)
- Guard pick_place_loop against overlapping goals (goal_in_flight flag)
- Use zip() instead of index-based iteration in joint_state_callback
- Remove unused Optional import from manipulation_monitor
- Add comment to bare except in pick_place_loop

Config:
- Rename task-constructor → pick-place-loop, mtc-pick-place →
  pick-place-node in panda_manifest.yaml to match actual demo node
- Restrict CORS origins from wildcard to localhost:8080/3000

Packaging:
- Add missing exec_depend entries in package.xml (rclpy, action_msgs,
  sensor_msgs, moveit_msgs, ros2_medkit_msgs)
- Pin ros2_medkit clone to configurable ARG ROS2_MEDKIT_REF in Dockerfile
- Remove rosdep || true fallback to fail on missing dependencies

run-demo.sh:
- Skip X11/xhost setup in headless mode or when DISPLAY is unset
- Add --gazebo flag to usage help text
- Fix image size estimate in output message

Docs:
- Update README to reflect Gazebo as default simulation mode
- Rename entity hierarchy entries to match updated manifest
ros2_medkit packages are not in rosdep indices (built from source),
so rosdep install always exits non-zero. The || true is necessary
but now has a comment explaining why.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Robot arm demo showcasing operations and trajectory control

2 participants